Skip to content

feat: powerlevel10k support and LACT R9700 tuning guide - #28

Merged
ulises-c merged 13 commits into
mainfrom
feat/p10k-lact
Jun 10, 2026
Merged

feat: powerlevel10k support and LACT R9700 tuning guide#28
ulises-c merged 13 commits into
mainfrom
feat/p10k-lact

Conversation

@ulises-c

@ulises-c ulises-c commented May 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • Powerlevel10k: adds zsh-theme-powerlevel10k package (Arch) and powerlevel10k brew formula (macOS); updates both zshrc.example files to source p10k when installed, falling back to the existing vcs_info prompt when it isn't
  • LACT: adds lact package entry (Arch); adds lact_r9700_tuning.md guide and lact_r9700.yaml config template; adds lact_default_backup.yaml stock config snapshot from live hardware
  • Claude config: registers the graphify skill trigger in CLAUDE.md; documents uv run --no-sync pytest requirement in TODO.md

LACT notes (R9700 AI Pro, live-tested on Sapphire/CachyOS)

Known active bugs (May 2026):

  • Fan curve and voltage offset are blocked on some units by an SMU firmware version mismatch (driver v46 vs card v50) — both gpu_od and pp_od_clk_voltage absent on affected hardware; AMD fix targeting ROCm 7.13 (ROCm #6101)
  • ppfeaturemask must be set via kernel boot parameter — modprobe silently strips the OD feature bit with no log warning
  • Power cap via hwmon confirmed working: range 210–300W (stock = 300W, not ~260W as initially estimated)

Minor patches applied during testing:

  • Corrected stock TDP from ~260W to confirmed 300W max
  • Fixed hardcoded card0 → dynamic AMD card lookup (card number varies by system)
  • Scoped SMU bug to cover voltage offset in addition to fan control (both blocked)
  • Capped performance profile at 300W (was 315W, which exceeds hardware max)
  • Added lact-cli headless reference and sysfs power-cap-only fallback for affected units

Test plan

  • p10k configure on fresh Arch install produces a working prompt; fallback vcs_info prompt works when p10k absent
  • lact installs cleanly via yay on CachyOS
  • lact cli power-limit get shows 210–300W range
  • After SMU fix ships: lact cli stats reports non-zero GFX clocks; fan curve and voltage offset take effect without config changes

🤖 Generated with Claude Code

ulises-c and others added 9 commits May 29, 2026 03:16
Adds p10k package entries (yay on Arch, brew on macOS) and updates both
zshrc examples to source the theme when installed, falling back to the
existing vcs_info prompt when it isn't. Instant-prompt block added at
the top of both files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLAUDE.md: registers the graphify skill so Claude auto-invokes it on
/graphify. TODO.md: documents that uv projects must use
`uv run --no-sync pytest` in .claude/test-cmd to avoid uv sync
reverting out-of-band package installs on every edit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lact_r9700_tuning.md covers ppfeaturemask prereq, apply steps,
voltage offset rationale, gaming vs inference profiles, and stability
testing. lact_r9700.yaml is a drop-in LACT config with -80mV offset,
210W cap, and a 5-point junction fan curve tuned for RDNA4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Arch-only for now; pairs with the new lact_r9700_tuning.md guide.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ramps from 30% at 50C to 60% at 75C and 80% at 90C junction.
Previous curve maxed at 40% at 90C — too conservative for sustained
inference load. Targets junction under ~80C with some noise tradeoff.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consolidates bottom of curve to one idle point (35C/25%) freeing up
slots for 70/75/80/90 steps. Gradual 7-8% increments per step keep
fan speed changes subtle while maintaining cooling past the knee.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ssive

Averages speeds between the conservative original (max 40% at 90C) and
the aggressive version (max 80% at 90C). Result: quiet below 70C, gentle
5C-step ramp to 60% at 90C junction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sk fix

- Add gpu_od health check as first step — some R9700 boards (ASUS Turbo
  vBIOS 115-G287BP00-100) have SMU v46/v50 mismatch that makes fan
  control a no-op; fan curve is silently ignored on affected units
- Fix ppfeaturemask guidance: must be kernel cmdline, not modprobe.d;
  driver silently strips OD feature bit (0x4000) from modprobe config
- Add sysfs fallback commands for voltage + power cap when LACT can't
  reach fan/clock registers
- Add 315W / -75mV performance profile from amd-r9700-vllm-toolboxes
- Add lact-cli reference (list-gpus, info only — all tuning is config-file)
- Update references with ROCm issues 6078/6101

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…MU bug

- Replace hardcoded card0 with dynamic AMD card lookup (card number varies)
- Correct stock power cap: 300W (confirmed), range 210-300W (not ~260W)
- Voltage offset is also blocked by SMU bug, not just fan control — both
  pp_od_clk_voltage and gpu_od are absent on affected units
- Cap performance profile at 300W max (not 315W which exceeds hw limit)
- Sysfs fallback section now accurately reflects power-cap-only capability
  on SMU bug units, with conditional voltage offset block for unaffected units

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ulises-c

Copy link
Copy Markdown
Owner Author

R9700 AI Pro — LACT findings from live testing

Documenting what we've learned from actually running this on the hardware (Sapphire R9700 AI Pro, headless CachyOS).

Hardware confirmed

  • Card: Sapphire Technology R9700 AI Pro (0x1002:0x7551, gfx1201/RDNA4)
  • vBIOS: 023.008.000.068.000001 (2025-07-25)
  • Card path: card1 (not card0 — varies by system)
  • Power cap range: 210W–300W (stock = 300W, not ~260W as initially documented)

Active bugs (as of May 2026)

1. SMU interface version mismatch — partially broken

Driver expects SMU v46 (0x2e), card ships with v50 (0x32).

On this Sapphire unit the impact is partial — worse on the ASUS Turbo variant:

Control Status
Fan spinning / RPM telemetry ✅ Works (confirmed: 20%, 893 RPM at idle)
Fan curve via LACT / gpu_od gpu_od path absent, fan curve in config is a no-op
Voltage offset (pp_od_clk_voltage) ❌ Path absent, LACT voltage setting is a no-op
Power cap (power1_cap hwmon) ✅ Works — lact cli power-limit set <W> confirmed
GFX clock reporting ❌ Stuck at 0 MHz in lact cli stats (SMU side-effect)

ROCm tracking issue: ROCm/ROCm#6101 (open, 54 comments)
AMD fix targeting TheRock / ROCm 7.13.

2. ppfeaturemask silently stripped by modprobe

Setting amdgpu.ppfeaturemask=0xfff7ffff via modprobe.d causes the driver to silently strip the OD feature bit (0x4000), loading 0xfff7bfff instead — no warning in dmesg. Must use kernel boot parameter, not modprobe.


What actually works headless right now

# Power cap — the only confirmed-working tuning lever
lact cli power-limit set 210   # quiet inference
lact cli power-limit get       # verify: 210W (range 210–300W)
lact cli stats                 # live temps, fan, clocks

The fan curve and voltage offset in lact_r9700.yaml are ready — they'll apply automatically once AMD ships SMU v50 driver support. No config changes needed when the fix arrives.


lact-cli headless reference

lact cli list                    # GPU IDs
lact cli stats                   # live clocks/temps/fan/power
lact cli info                    # static hardware info
lact cli power-limit get/set     # only tuning lever with a direct CLI command
lact cli profile list/get/set    # profile management
lact cli snapshot                # debug dump

No CLI command for voltage offset — config file only.

Captured from Sapphire R9700 AI Pro on CachyOS 2026-05-29.
Baseline to restore from if tuning goes wrong.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ulises-c

Copy link
Copy Markdown
Owner Author

Power cap impact by workload type

Quick reference for how the 210W vs 300W cap affects different scenarios on the R9700 AI Pro.

The key factor is what's bottlenecking the workload — compute (shader throughput, clock-sensitive) or memory bandwidth (VRAM bandwidth, largely clock-insensitive).

Inference

Phase Bottleneck 210W vs 300W impact
Prefill (prompt processing) Compute-bound ~15% slower time-to-first-token
Decode (token generation) Memory-bandwidth bound <5% — essentially free

Decode fetches the full model weights from VRAM each token. At 644 GB/s the shaders sit mostly idle waiting on memory — capping clocks barely moves tokens/sec. For typical chat (short prompts, long outputs) the cap is nearly invisible. For long-context or RAG workloads where prefill dominates, you'll feel the ~15% TTFT hit.

Training / SFT

Most impacted. Forward pass, backward pass, and gradient computation are all sustained matrix ops that max out shader throughput. The GPU hits the power cap immediately and throttles clocks to stay there.

Estimated impact: ~15–25% slower depending on batch size and model architecture. Larger batches are more compute-efficient and feel the cap more; tiny batches less so.

For SFT: run at 300W.

Gaming

Most sensitive. Rasterization and shading are sustained compute-bound by design — the GPU is meant to run at max clocks the whole time. 210W vs 300W is a 30% power reduction → roughly 15–25% lower FPS in sustained heavy scenes (open world, ray tracing, dense geometry). Lighter scenes that don't push TDP won't be affected.

Summary

Workload Recommended cap Reason
SFT / training 300W Fully compute-bound, every watt counts
Gaming 300W Sustained compute-bound, FPS scales with clocks
Long-context inference / RAG 300W or 210W Prefill is compute-bound; judgment call on noise vs TTFT
Chat inference (short prompts) 210W Decode dominates, cap is nearly free
Idle / light use 210W No reason to run hot

Once the SMU bug is fixed and voltage offset becomes available, -75 to -80mV will recover most of the performance lost to the power cap — you get ~same compute at lower thermals rather than just trading performance for quiet.

@ulises-c ulises-c changed the title feat: powerlevel10k support and LACT R9700 tuning guide feat(lact): LACT setup and tuning guide for AMD Radeon AI PRO R9700 May 29, 2026
@ulises-c ulises-c changed the title feat(lact): LACT setup and tuning guide for AMD Radeon AI PRO R9700 feat: powerlevel10k support and LACT R9700 tuning guide May 29, 2026
ulises-c and others added 3 commits June 9, 2026 23:05
…pport

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the generated p10k.zsh to the repo and wires it into setup.sh
with the same backup-on-diff pattern used for zshrc/tmux/ghostty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
shellcheck picks up .zsh files and can't parse zsh-specific syntax.
Renaming to .example matches the zshrc.example convention already used
in the repo for dotfile templates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ulises-c
ulises-c marked this pull request as ready for review June 10, 2026 06:39
@ulises-c
ulises-c merged commit b23cf9e into main Jun 10, 2026
3 checks passed
@ulises-c
ulises-c deleted the feat/p10k-lact branch June 10, 2026 06:39
@ulises-c ulises-c mentioned this pull request Jun 10, 2026
@ulises-c ulises-c linked an issue Jun 10, 2026 that may be closed by this pull request
ulises-c added a commit that referenced this pull request Jun 10, 2026
…ified stack (#36)

Merge origin/main (PRs #28 powerlevel10k/LACT, #35 railguard fixes,
#38 claude-hud) into the unification branch. The two PRs that touched the
legacy setup stack landed while this branch converted it to shims, so their
features are ported into the unified system as part of the conflict
resolution:

- packages.json gains zsh-theme-powerlevel10k (arch/yay, high) and lact
  (arch/yay, medium) — the entries main added to the now-deleted
  linux-desktop/linux_desktop_packages.json.
- The shared desktop flow (lib/core.sh) deploys ~/.p10k.zsh from
  linux-desktop/p10k.zsh.example via deploy_config — the step main added to
  the legacy linux-desktop/setup.sh, which stays a shim.
- Everything else from main merges clean: zshrc.examples, ghostty font,
  p10k.zsh.example, LACT configs/docs, railguard and claude-hud config.

Gate: per-platform full-flag dry-run diffed against the pre-merge snapshot —
macOS and server unchanged (timestamp only); ubuntu/arch show exactly the
intended additions (p10k deploy, the two arch packages, and the zshrc
update caused by main's new zshrc.example content). dryrun-smoke 4/4;
shellcheck + jq clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LACT install and config

1 participant